package nina.yiyou.salary.process.global

import com.google.common.collect.ImmutableSet
import nina.yiyou.salary.input.util.InputPathResolver
import nina.yiyou.salary.output.util.KeyPrefixPrepender

import java.nio.file.Path
import java.time.LocalDate

class GlobalResultMaker {

  interface Result {

    Path workshopPath()

    Salary salaryTime()

    Insurance insuranceColumn()

    Set<String> attendIgnore()

    Path resolvePath(String key)

    Map<String, ?> toMap()
  }

  interface Salary {

    LocalDate start()

    LocalDate end()
  }

  interface Insurance {

    String total()

    String pension()

    String medical()

    String unemploy()
  }

  GlobalResultMaker(Map<String, String> globalMap, Path workshopPath) {
    _globalMap = globalMap
    _workshopPath = workshopPath
  }

  Result make() {
    LocalDate salaryStart = getStartTime()
    LocalDate salaryEnd = salaryStart.plusMonths(1).minusDays(1)
    def salary = new Salary() {
      @Override
      LocalDate start() {
        return salaryStart
      }

      @Override
      LocalDate end() {
        return salaryEnd
      }
    }

    def getGlobal = { String k ->
      assert _globalMap[k]
      return _globalMap[k]
    }
    def insurance = new Insurance() {
      @Override
      String total() {
        return getGlobal('社保列.合计')
      }

      @Override
      String pension() {
        return getGlobal('社保列.基本养老')
      }

      @Override
      String medical() {
        return getGlobal('社保列.基本医疗')
      }

      @Override
      String unemploy() {
        return getGlobal('社保列.失业保险')
      }
    }

    Map computeMap = new GlobalMapProcessor(_globalMap, salaryStart, salaryEnd, _workshopPath).process()
    Map resultMap = makeResult([
        ['全局', _globalMap],
        ['计算', computeMap],
    ])

    return new Result() {
      @Override
      Path workshopPath() {
        return _workshopPath
      }

      @Override
      Salary salaryTime() {
        return salary
      }

      @Override
      Insurance insuranceColumn() {
        return insurance
      }

      @Override
      Set<String> attendIgnore() {
        return getAttendIgnore(getGlobal('考勤假人'))
      }

      @Override
      Path resolvePath(String key) {
        return InputPathResolver.create(_workshopPath, _globalMap, key).resolve()
      }

      @Override
      Map<String, ?> toMap() {
        return resultMap
      }
    }
  }

  private LocalDate getStartTime() {
    def year = _globalMap['年'] as int
    def month = _globalMap['月'] as int

    def day = _globalMap['日'] as int
    if (day < 0) {
      return LocalDate.of(year, month, -day).minusMonths(1)
    }
    return LocalDate.of(year, month, day)
  }

  private Set<String> getAttendIgnore(String ignoreStr) {
    return ImmutableSet.copyOf(ignoreStr.split(/\|\s*/))
  }

  private Map<String, ?> makeResult(List list) {
    return list
        .collect { String p, Map m -> new KeyPrefixPrepender(m, p).prepend() }
        .inject { sum, line -> sum + line }
  }

  private final Map<String, String> _globalMap

  private final Path _workshopPath
}
